#include "stm32f10x.h"
#include "led_driver.h"
#include "beeper.h"
#include "adc.h"
#include "OLED.h"
#include "Motor.h"
#include "Key.h"
#include "dht11.h"
#include "Delay.h"
#include "esp8266.h"
#include "usart.h"

// 状态变量
static uint8_t KeyNum;
static int8_t Speed;
static uint8_t led1_status = 0;
static uint8_t fan_status = 0;
static uint8_t alarm_status = 0;

static uint8_t cloud_manual_control = 0;  // 0=自动模式, 1=云端手动控制

// 控制阈值定义
#define TEMP_FAN_ON      30
#define TEMP_FAN_OFF     29
#define LIGHT_LED_ON     4000  
#define LIGHT_LED_OFF    200 
#define SOIL_ALARM_THRESHOLD 50

// 传感器数据结构
typedef struct {
    uint16_t light_raw;
    uint16_t soil_raw;
    uint16_t soil_percent;
    uint16_t light_percent;
    uint8_t temperature;
    uint8_t humidity;
} SensorData_t;

// 在传感器数据结构后添加MQTT相关变量
static uint32_t last_mqtt_send_time = 0;
#define MQTT_SEND_INTERVAL 5000  // 5秒发送一次

// 在函数声明部分添加
static void MQTT_Send_SensorData(const SensorData_t* data);

// 函数声明
static void System_Init(void);
static void Sensor_Data_Collect(SensorData_t* data);
static void Key_Process(void);
static void Auto_Control(const SensorData_t* data);
static void Display_Update(const SensorData_t* data);


// 修改设备控制函数
void CloudControl_LED(bool state)
{
    cloud_manual_control = 1;  // 进入手动控制模式
    if(state) {
        led_on(LED1);
        led1_status = 1;
    } else {
        led_off(LED1);
        led1_status = 0;
    }
}

void CloudControl_Buzzer(bool state)
{
    cloud_manual_control = 1;  // 进入手动控制模式
    if(state) {
        beep_on();
        alarm_status = 1;
    } else {
        beep_off();
        alarm_status = 0;
    }
}

void CloudControl_Motor(bool state)
{
    cloud_manual_control = 1;  // 进入手动控制模式
    if(state) {
        Speed = -30;
        Motor_SetSpeed(Speed);
        fan_status = 1;
    } else {
        Motor_SetSpeed(0);
        fan_status = 0;
        Speed = 0;
    }
}


int main(void)
{
    // 系统初始化
    SystemInit();
    led_init();
		USART_Config();
	
	  // 先初始化OLED并显示稳定界面
    OLED_init();
    OLED_Clear();
    OLED_ShowString(1, 1, "Init OLED...OK");
    Delay_ms(500);  // 确保OLED稳定显示
    
    // 先设置SysTick为最高优先级
    NVIC_SetPriority(SysTick_IRQn, 0);
    
    Usart_SendString(USART1, "System Start\r\n");
    
    // 第一阶段：快速初始化所有基础外设

    beeper_init();
    adc_init();
    dht11_init();
    Motor_Init();
    Key_Init();
    Speed = 0;
    
    // 显示系统启动信息
    OLED_Clear();
    OLED_ShowString(1, 1, "System Starting...");
    
    SensorData_t sensor_data = {0};
    
    // 第二阶段：初始化ESP8266（此时中断优先级已降低）
    Usart_SendString(USART1, "Init ESP8266...\r\n");
    ESP8266_Init();
    
    Usart_SendString(USART1, "Connecting WiFi...\r\n");
    ESP8266_StaTcpClient();
    
    Usart_SendString(USART1, "Enter Main Loop\r\n");
    OLED_Clear();
    
    uint32_t last_display_time = 0;
    static uint32_t tick_counter = 0;
    
    while(1)
    {
        // 第一步：数据采集
        Sensor_Data_Collect(&sensor_data);
        
        // 第二步：按键处理
        Key_Process();
        
        // 第三步：自动控制决策
        Auto_Control(&sensor_data);
        
        // 第四步：本地显示更新
        tick_counter++;
        if(tick_counter >= 25) {
            Display_Update(&sensor_data);
            tick_counter = 0;
        }
        
        // 第五步：MQTT数据上传
        static uint32_t current_time = 0;
        current_time += 50;
        if(current_time - last_mqtt_send_time >= MQTT_SEND_INTERVAL) {
            MQTT_Send_SensorData(&sensor_data);
            last_mqtt_send_time = current_time;
        }
        
        // 第六步：处理MQTT控制命令（新增）
        MQTT_Command_Process();
        
        Delay_ms(20);
    }
}


/**
  * @brief  发送传感器数据到MQTT
  * @param  data: 传感器数据结构指针
  */
static void MQTT_Send_SensorData(const SensorData_t* data)
{
    char json_buffer[256];
    
    // 构建JSON数据
    // 使用反斜杠转义双引号，符合AT命令格式要求
    sprintf(json_buffer, 
            "{\\\"temperature\\\":%.1f \\\, \\\"humidity\\\":%.1f \\\, \\\"light_intensity\\\":%d \\\, \\\"soil_moisture\\\":%.1f}",
            (float)data->temperature,      // 环境温度
            (float)data->humidity,         // 环境湿度
            data->light_raw,               // 光照强度
            (float)data->soil_percent);    // 土壤湿度
    
    // 发送到MQTT
    char cmd[512];
    sprintf(cmd, "AT+MQTTPUB=0,\"attributes\",\"%s\",0,0", json_buffer);
    
    if(ESP8266_Cmd(cmd, "OK", NULL, 3000)) {
        Usart_SendString(USART1, "MQTT Publish Success: ");
        Usart_SendString(USART1, cmd);
        Usart_SendString(USART1, "\r\n");
    } else {
        Usart_SendString(USART1, "MQTT Publish Failed\r\n");
        // 如果发布失败，尝试重新连接MQTT
        MQTT_Init();
    }
}


/**
  * @brief  传感器数据采集
  * @param  data: 传感器数据结构指针
  */
static void Sensor_Data_Collect(SensorData_t* data)
{
    // 读取ADC数据
    data->light_raw = adc_read(0);
    data->soil_raw = adc_read(1);
    
    // 读取温湿度
    int ret = dht11_read(&data->temperature, &data->humidity);
    if (ret != 0) {
        // DHT11读取失败处理
        data->temperature = 25;
        data->humidity = 60;
    }

    // 转换为百分比（光照：4095=0%，0=100%）
    data->soil_percent = (4095U - data->soil_raw) * 100U / 4095U;
    data->light_percent = (4095U - data->light_raw) * 100U / 4095U;
}

/**
  * @brief  按键处理
  */
static void Key_Process(void)
{
    KeyNum = Key_GetNum();
    if (KeyNum == 1)  // 按键1按下
    {
        if (fan_status) {
            // 风扇开启状态下调整速度
            Speed += 10;
            if (Speed > 0) {
                Speed = -30;  // 循环调整速度
            }
            Motor_SetSpeed(Speed);
        }
    }
    else if (KeyNum == 2)  // 假设按键2用于切换模式
    {
        // 切换手动/自动模式
        cloud_manual_control = !cloud_manual_control;
        if(cloud_manual_control) {
            Usart_SendString(USART1, "Manual Mode Enabled\r\n");
        } else {
            Usart_SendString(USART1, "Auto Mode Enabled\r\n");
        }
    }
}

/**
  * @brief  自动控制决策
  * @param  data: 传感器数据结构指针
  */
static void Auto_Control(const SensorData_t* data)
{
    // 如果处于云端手动控制模式，则不执行自动控制
    if(cloud_manual_control) {
        return;
    }
    
    // 风扇温度控制 - 独立控制，不影响其他功能
    if (data->temperature >= TEMP_FAN_ON && !fan_status)
    {
        // 温度达到阈值且风扇未开启，开启风扇
        Speed = -30;  // 设置初始速度
        Motor_SetSpeed(Speed);
        fan_status = 1;
    }
    else if (data->temperature <= TEMP_FAN_OFF && fan_status)
    {
        // 温度降低且风扇开启，关闭风扇
        Motor_SetSpeed(0);
        fan_status = 0;
        Speed = 0;
    }
    
    // 补光LED控制 - 独立控制，可以与蜂鸣器同时工作
    if (data->light_raw > LIGHT_LED_ON) 
    {
        // 光照很弱时打开补光LED（不管蜂鸣器是否在响）
        if (!led1_status) {
            led_on(LED1);
            led1_status = 1;
        }
    }
    else if (data->light_raw < LIGHT_LED_OFF)
    {
        // 光照足够时关闭补光LED
        if (led1_status) {
            led_off(LED1);
            led1_status = 0;
        }
    }
    
    // 土壤湿度报警控制 - 独立控制，可以与LED同时工作
    if (data->soil_percent < SOIL_ALARM_THRESHOLD)
    {
        // 土壤湿度低于阈值，开启蜂鸣器（不管LED是否亮）
        if (!alarm_status) {
            beep_on();
            alarm_status = 1;
        }
    }
    else
    {
        // 土壤湿度恢复正常，关闭蜂鸣器
        if (alarm_status) {
            beep_off();
            alarm_status = 0;
        }
    }
}

/**
  * @brief  显示更新
  * @param  data: 传感器数据结构指针
  */
static void Display_Update(const SensorData_t* data)
{
    OLED_Clear();
    
    // 显示传感器数据
    OLED_ShowString(1, 1, "Light:"); 
    OLED_ShowNum(1, 7, data->light_percent, 3);
    OLED_ShowChar(1, 10, '%');
    
    OLED_ShowString(2, 1, "Temp :"); 
    OLED_ShowNum(2, 7, data->temperature, 2); 
    OLED_ShowChar(2, 9, 'C');
    
    OLED_ShowString(3, 1, "Humi :"); 
    OLED_ShowNum(3, 7, data->humidity, 2);     
    OLED_ShowChar(3, 9, '%');
    
    OLED_ShowString(4, 1, "Soil :"); 
    OLED_ShowNum(4, 7, data->soil_percent, 2); 
    OLED_ShowChar(4, 9, '%');
    
    // 显示系统状态
    OLED_ShowString(1, 12, "FAN:");
    OLED_ShowString(1, 16, fan_status ? "1" : "0");
    
    OLED_ShowString(2, 12, "LED:");
    OLED_ShowString(2, 16, led1_status ? "1" : "0");
    
    OLED_ShowString(3, 11, "ALRM:");
    OLED_ShowString(3, 16, alarm_status ? "1" : "0");
		
		    // 显示模式状态（新增）
    OLED_ShowString(4, 11, cloud_manual_control ? "M" : "A");
    
    // 显示当前速度（如果风扇开启）
    if (fan_status) {
        OLED_ShowString(4, 11, "S:");
        OLED_ShowSignedNum(4, 13, Speed, 3);
    }
}

